package com.alan.cueencoding.service;

import com.alan.cueencoding.dto.ConvertDTO;
import com.alan.cueencoding.util.FileEncodeUtil;
import com.alan.cueencoding.util.MatchingResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.multipart.MultipartFile;
import org.thymeleaf.util.StringUtils;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author Alan.Xiao
 * @date 2022/10/4
 */
@Service
@Slf4j
public class CueEncodingService {


    public List<MatchingResult> processEncoding(MultipartFile file) {
        try {
            byte[] fileBytesFromFile = this.getFileBytesFromFile(file);
            List<String> matchPatterns = this.resolveContentMatchPatterns(file);

            List<MatchingResult> matchingFileEncodings =
                    FileEncodeUtil.findMatchingFileEncodings(fileBytesFromFile, matchPatterns)
                            .stream()
                                .peek(result -> result.setFileName(file.getOriginalFilename()))
                                    .collect(Collectors.toList());

            return matchingFileEncodings;
        } catch (Exception ex) {
            log.error("Error occurred during processing the cue file", ex);
        }

        return Collections.emptyList();
    }

    /**
     * 指定匹配的规则。默认从文件名中截取并分拆成单个词
     *
     * @param file
     * @return
     */
    private List<String> resolveContentMatchPatterns(MultipartFile file) {
        return Arrays.stream(file.getOriginalFilename().substring(0, 4).split(""))
                .filter(pattern -> !StringUtils.isEmptyOrWhitespace(pattern)).collect(Collectors.toList());
    }

    private byte[] getFileBytesFromFile(MultipartFile file) throws IOException {
        InputStream fos = file.getInputStream();
        int available = fos.available();
        byte[] bytes = new byte[available];
        fos.read(bytes);
        return bytes;
    }

    public void convertAndDownload(ConvertDTO convertDTO) {
        String fileName = convertDTO.getFileName();
        byte[] decodedContent = convertDTO.getDecodedContent().getBytes();

        HttpServletResponse response = ((ServletRequestAttributes)
                RequestContextHolder.getRequestAttributes()).getResponse();
        ByteArrayInputStream fis = null;
        BufferedInputStream bins = null;
        OutputStream outs = null;
        BufferedOutputStream bouts = null;

        try {
            fis = new ByteArrayInputStream(decodedContent);
            bins = new BufferedInputStream(fis);
            outs = response.getOutputStream();
            bouts = new BufferedOutputStream(outs);
            response.setContentType("application/octet-stream");
            response.setHeader("Content-Disposition","attachment");
            response.setHeader("filename", URLEncoder.encode(fileName, "UTF-8"));
            int bytesRead = 0;
            byte[] buffer = new byte[8192];
            while ((bytesRead = bins.read(buffer, 0, 8192)) != -1) {
                bouts.write(buffer, 0, bytesRead);
            }
            bouts.flush();
        } catch (IOException exception) {
            throw new RuntimeException(exception);
        } finally {
            try {
                bins.close();
                fis.close();
                outs.close();
                bouts.close();
            } catch (IOException e) {
                log.error("删除临时文件出错！", e);
            }
        }
    }
}

